﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Timers;
using System.Threading.Tasks;
using BLL = KC.Business.Meta;
using DAL = KC.DataAccess.Meta;
using C = KC.Constants;
using Logger = KC.Logging.Logger;


namespace KC.Presentation.Meta
{
	public partial class Service1 : ServiceBase
	{
		public Service1() { InitializeComponent(); }
		private Timer timer;
		private bool hasTicked = false;
		private DAL.MetaDataContext dc = new DAL.MetaDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["Meta"].ConnectionString);

		protected override void OnStart(string[] args)
		{
			Logger.LogError(Logger.Project.Meta, Logger.ErrorLevel.Information, "Mechanized Ethereal Transaction Analyzer starting up");
			timer = new Timer();
			timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
			timer.Interval = int.Parse(System.Configuration.ConfigurationManager.AppSettings["TimerInterval"].ToString());
			timer.Enabled = true;
			timer.Start();
		}

		protected override void OnStop()
		{
			Debug.WriteLine("Shutting down...");
			Logger.LogError(Logger.Project.Meta, Logger.ErrorLevel.Information, "Mechanized Ethereal Transaction Analyzer shutting down");
		}

		void timer_Elapsed(object sender, ElapsedEventArgs e)
		{
			if (!hasTicked) {
				Debug.WriteLine("First tick firing");
				hasTicked = true;
				System.Threading.Thread.Sleep(2500);
				Logger.LogError(Logger.Project.Meta, Logger.ErrorLevel.Information, "Startup Complete"); }

			// Get jobs that have already been enqueued, and that run regularly and are due or overdue
			Debug.WriteLine("Checking job runs...");
			var PendingJobs = BLL.Meta.GetPendingJobs(ref dc);
			var OverdueJobs = BLL.Meta.GetOverdueJobs(ref dc);
			Debug.WriteLine("- " + PendingJobs.Count().ToString() + " Pending job runs");
			Debug.WriteLine("- " + OverdueJobs.Count().ToString() + " Overdue job runs");

			// Run job queue
			Parallel.ForEach(OverdueJobs, run => { RunJob(ref dc, ref run); });
			Parallel.ForEach(PendingJobs, run => { RunJob(ref dc, ref run); });
		}

		private static void RunJob(ref DAL.MetaDataContext dc, ref DAL.JobRun run)
		{
			Debug.WriteLine("Running job run " + run.Id.ToString() +
				" \r\n - Job:         " + run.Job.Enum + "." + run.Job.Name +
				" \r\n - Thread:      " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() +
				" \r\n - Iteration #: " + run.Job.Iterations.ToString());
			System.Threading.Thread.CurrentThread.Name = "Process JobRun " + run.Id.ToString();
			if (dc.Connection.State != ConnectionState.Open) dc.Connection.Open();
			switch (run.Job.Enum) {
				case "MV":
					BLL.Meta.ProcessJobMV(ref dc, ref run);
					break; }
		}
	
	}
}
